package com.goddess.yeecolor.tools;

import android.Manifest;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.provider.MediaStore;
import android.support.v4.content.FileProvider;


import com.goddess.yeecolor.interfaceAll.OnPermissionRequestListener;

import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Date;

/**
 * 作者：Shelby.Lee on 2017/4/11.
 */

public class PublicUtils {

    public static final String IMG_URL = Environment.getExternalStorageDirectory() + "/Goddess/Img/";

    /**
     * 启动相簿
     */
    public static void openAlbumActivity(int requestCode, Activity mContext) {
        Intent intent = new Intent();
        intent.setType("image/*");
        intent.setAction(Intent.ACTION_PICK);
        intent.setData(MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
        mContext.startActivityForResult(intent, requestCode);
    }

    /**
     * 启动相机
     */
    public static void openCameraActivity(int requestCode, String cameraUri, Activity mContext) {
        Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        Uri uri;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            uri = FileProvider.getUriForFile(mContext, "com.yeecolor.goddess.fileprovider", new File(cameraUri));
        } else {
            uri = Uri.fromFile(new File(cameraUri));
        }
        intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
        mContext.startActivityForResult(intent, requestCode);
    }

    /**
     * 用来处理调用系统相册获取的图片。
     * <p>
     * 1.现根据intent，解决兼容性，获取文件的绝对路径
     * 2.根据统一的绝对路径，获取到文件在存储卡里的真实路径
     * 3.根据图片的真实路径，对图片进行压缩（按比例压缩和压缩质量）
     * 4.压缩完图片之后，将压缩后的图片以file的形式保存到本地
     * 5.将压缩后的文件路径返回
     *
     * @param data 调用系统相册返回的实体。
     */
    public static String handleImage(Intent data, Context mContext) throws NullPointerException {
        String path = getFilePath(data, mContext);//获取统一的绝对路径，解决兼容问题
        String truePath = getTrueFilePath(path);//获取在sd卡中的真实路径
        String thumbnail = compressImage(truePath);//此步进行大小、质量的压缩，并生成缩略图存储到本地，返回的值为缩略图的本地地址
        return thumbnail;
    }

    /**
     * 根据调用系统图库获返回的数据，获取该图片在本地的实际路径
     * <p>
     * 1.先解决兼容性问题，获取统一的绝对路径
     * 2.根据获取的统一绝对路径转为实际路径并返回
     *
     * @param data 调用系统图库返回的数据intent
     * @return 该图片在本地的实际路径
     */
    public static String getOriginPathWithAlbum(Intent data, Context mContext) {
        String path = getFilePath(data, mContext);
        return getTrueFilePath(path);
    }

    /**
     * 将不同系统相册返回的路径统一
     */
    private static String getFilePath(Intent data, Context mContext) {
        String filePath = null;
        String[] projection = {MediaStore.Images.Media.DATA};
        Cursor cursor = mContext.getContentResolver().query(data.getData(), projection, null, null, null);
        if (null != cursor && cursor.getCount() > 0) {
            int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
            cursor.moveToFirst();
            filePath = cursor.getString(column_index);
            cursor.close();
        }

        return filePath;
    }

    /**
     * 根据解析后的绝对路径，获取在sd卡中的真实路径
     *
     * @param path 统一后的绝对路径
     * @return 在sd卡中的真实路径
     */
    private static String getTrueFilePath(String path) {
        String[] dataStr = path.split("/");
        String fileTruePath = "/sdcard";
        for (int i = 4; i < dataStr.length; i++) {
            fileTruePath = fileTruePath + "/" + dataStr[i];
        }

        return fileTruePath;
    }

    /**
     * 按比例缩小图片
     *
     * @param srcPath 图片的地址
     * @return 压缩后的图片
     */
    public static String compressImage(String srcPath) {
        BitmapFactory.Options newOpts = new BitmapFactory.Options();
        //开始读入图片，此时把options.inJustDecodeBounds 设回true了
        newOpts.inJustDecodeBounds = true;
        Bitmap bitmap = BitmapFactory.decodeFile(srcPath, newOpts);//此时返回bm为空

        newOpts.inJustDecodeBounds = false;
        int w = newOpts.outWidth;
        int h = newOpts.outHeight;
        //现在主流手机比较多是800*480分辨率，所以高和宽我们设置为
        float hh = 800f;//这里设置高度为800f
        float ww = 480f;//这里设置宽度为480f
        //缩放比。由于是固定比例缩放，只用高或者宽其中一个数据进行计算即可
        int be = 1;//be=1表示不缩放
        if (w > h && w > ww) {//如果宽度大的话根据宽度固定大小缩放
            be = (int) (newOpts.outWidth / ww);
        } else if (w < h && h > hh) {//如果高度高的话根据宽度固定大小缩放
            be = (int) (newOpts.outHeight / hh);
        }
        if (be <= 0) {
            be = 1;
        }
        newOpts.inSampleSize = be;//设置缩放比例
        //重新读入图片，注意此时已经把options.inJustDecodeBounds 设回false了
        bitmap = BitmapFactory.decodeFile(srcPath, newOpts);
        return compressImage(bitmap);//压缩好比例大小后再进行质量压缩
    }

    /**
     * 压缩质量
     *
     * @param image bitmap图片
     * @return 压缩后的图片
     */
    private static String compressImage(Bitmap image) {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        image.compress(Bitmap.CompressFormat.JPEG, 100, baos);//质量压缩方法，这里100表示不压缩，把压缩后的数据存放到baos中
        int options = 100;
        while (baos.toByteArray().length / 1024 > 100) {    //循环判断如果压缩后图片是否大于100kb,大于继续压缩
            baos.reset();//重置baos即清空baos
            options -= 10;//每次都减少10
            image.compress(Bitmap.CompressFormat.JPEG, options, baos);//这里压缩options%，把压缩后的数据存放到baos中

        }
        ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());//把压缩后的数据baos存放到ByteArrayInputStream中
        Bitmap bitmap = BitmapFactory.decodeStream(isBm, null, null);//把ByteArrayInputStream数据生成图片
        return saveBitmapFile(bitmap);
    }

    /**
     * 将裁剪的图片保存
     *
     * @param bitmap 1
     */
    private static String saveBitmapFile(Bitmap bitmap) {
        String imgUri = IMG_URL + new Date().getTime();
        File teamIcon = new File(imgUri);
        if (!teamIcon.exists()) {
            if (new File(IMG_URL).mkdirs()) {
                teamIcon = new File(imgUri);
            }
        }

        try {
            BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(teamIcon));
            bitmap.compress(Bitmap.CompressFormat.JPEG, 100, bos);
            bos.flush();
            bos.close();
            return imgUri;
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 动态请求相机权限，需要两个权限，一个是外部存储卡写入，一个是相机权限
     *
     * @param mContext                    调用的Activity
     * @param requestCode                 权限的请求码
     * @param onPermissionRequestListener 对于权限的判断监听，onSuccess回调代表要么系统不够6.0，要么已经获取权限，可以直接调用打开相机函数
     */
    public static void getCameraPermission(Activity mContext, int requestCode,
                                           OnPermissionRequestListener onPermissionRequestListener) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            if (mContext.checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) !=
                    PackageManager.PERMISSION_GRANTED || mContext.checkSelfPermission(Manifest.permission.CAMERA)
                    != PackageManager.PERMISSION_GRANTED) {
                mContext.requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE,
                        Manifest.permission.CAMERA}, requestCode);
            } else {
                onPermissionRequestListener.onSuccess();
            }
        } else {
            onPermissionRequestListener.onSuccess();
        }
    }

    /**
     * 动态获取存储卡写入权限
     *
     * @param mContext                    调用的activity
     * @param requestCode                 权限请求码
     * @param onPermissionRequestListener 权限判断监听，系统低于6.0或者已经获取权限回调onSuccess。
     */
    public static void getWriteExternalStoragePermission(Activity mContext, int requestCode
            , OnPermissionRequestListener onPermissionRequestListener) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            if (mContext.checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
                mContext.requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, requestCode);
            } else {
                onPermissionRequestListener.onSuccess();
            }
        } else {
            onPermissionRequestListener.onSuccess();
        }
    }


    /**
     * 用于调用系统相机时，传入的本地保存地址
     *
     * @return 拍照之后保存的地方。
     */
    public static String getCameraUri() {
        Date date = new Date();
        return IMG_URL + date.getTime() + ".jpg";
    }

    /**
     * 将字符串转成MD5值
     *
     * @param string 1
     * @return 1
     */
    public static String stringToMD5(String string) {
        byte[] hash;

        try {
            hash = MessageDigest.getInstance("MD5").digest(string.getBytes("UTF-8"));
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
            return null;
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
            return null;
        }

        StringBuilder hex = new StringBuilder(hash.length * 2);
        for (byte b : hash) {
            if ((b & 0xFF) < 0x10)
                hex.append("0");
            hex.append(Integer.toHexString(b & 0xFF));
        }

        return hex.toString().toUpperCase();
    }
}
